﻿using IcsSEMCtrl.Com.FieldBus;
using IcsSEMCtrl.Service;
using IcsSEMCtrl.Service.Logger;
using IcsSEMCtrl.Util.Client;
using Lifter;
using Lifter.Device;
using Lifter.Gui.Monitor.Panels;
using Lifter.Utility;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using TKT.Lifter.CIM.Lifter.Global;
using TKT.Lifter.CIM.Lifter.Gui.Monitor.Popups;
using static IcsSEMCtrl.Service.PlaybackManager;

namespace Lifter.Gui.Monitor.Popups
{
    public partial class PlayBackControls : UIForm
    {              
        private string localDir = string.Empty;           //Play Back LogFile的真实路径
        private string strBaseLocalDir = string.Empty;    //Basic LogFile的基础路径      

        #region 对象获取
        private LifterMainForm m_frmMain;
        private PlaybackManager m_PlayManager = new PlaybackManager();
        
        #endregion
        private bool onPlaying = false;  //是否启动PlayBack
        private bool bPaused = false;    //是否暂停PlayBak
        private bool onReading = false;  //是否正在读取数据
        private int curHourIndex = -1;    //当前加载的哪个小时的数据
        private int curIndex = 0;        //当前播放是这一个小时的第几个数据
        private int delayTime = 100;     //播放速率
        private int playEndIndex = 0;    //当前播放的这一个小时的数据量
        private int trackBarValue = 0;   //Track Bar的进度值

        //PlayBack
        private Dictionary<string, string> m_OldStringDic = new Dictionary<string, string>();
        public static Action<string, string> PlaybackEventHandler;



        public PlayBackControls()
        {
            this.InitializeComponent();
            this.ApplyResource(this);
        }
        ComponentResourceManager crm;
        /// <summary>
        /// 根据用户选择中英文
        /// </summary>
        /// <param name="control"></param>
        public void ApplyResource(Control control)
        {
            LifterSEM lifterSEM = (LifterSEM)Naming.GetDeviceManager().GetDevice();
            if (lifterSEM.LanguageType.Equals("en"))
            {
                crm = new ComponentResourceManager(typeof(TKT.Lifter.CIM.LanguageType.Resource_en));
                control.Text = "Play Back";
            }
            else
            {
                crm = new ComponentResourceManager(typeof(TKT.Lifter.CIM.LanguageType.Resource_zh));
                control.Text = "回放";
            }
            this.UpdateControlsLanguage(control);
        }
        /// <summary>
        /// 更新中英文切换
        /// </summary>
        /// <param name="control"></param>
        public void UpdateControlsLanguage(Control control)
        {
            foreach (Control item in control.Controls)
            {
                if (string.IsNullOrEmpty(control.Name))
                {
                    crm.ApplyResources(item, item.Name);
                }
                else
                {
                    crm.ApplyResources(item, control.Name + "." + item.Name);
                }
                if (item.HasChildren)
                {
                    UpdateControlsLanguage(item);
                }
            }
        }
        private void PlayBackControls_Load(object sender, EventArgs e)
        {           
            this.InitialCombox();          
            this.initProc();
            LifterMainForm.PlaybackMode = true;
            AbstractFieldBusDriver.m_PlaybackMode = true;
        }
        
        private void PlayBackControls_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.onPlaying = false;
            
            AbstractFieldBusDriver.m_PlaybackMode = false;
            LifterMainForm.PlaybackMode = false;
            this.m_PlayManager.CloseLogFile();
            MainTransferQueuePanel mainTransferQueuePanel = (MainTransferQueuePanel)SimpleCache.GetObject("OperationForm", "MainTransferQueuePanel");
            mainTransferQueuePanel.UpdateDelegate();
        }

        //初始化ComboBox
        private void InitialCombox()
        {
            //1.Play Speed
            this.cbx_Speed.SelectedIndex = 2;
            cbx_SelectedHour.SelectedIndex = 0;

            //2.Combox Disable
            this.cbx_Speed.Enabled = false;
            this.cbx_SelectedHour.Enabled = false;
        }

        //Play Back初始化 - 路径加载 + Layout准备
        private void initProc()
        {
            this.btnSelectDir.Enabled = true;
            this.strBaseLocalDir = Application.StartupPath;

            //1.显示路径 + 真实使用路径赋值
            this.txt_LocalDir.Text = this.localDir = this.strBaseLocalDir;

            //2.清除IOManager的EventIO数据
            //this.m_IOManager.ClearAllEventIO();

            //3.Layout界面准备

        }

        //Local模式下选择PlayBack的路径
        private void btnSelectDir_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowser = new FolderBrowserDialog();
            folderBrowser.Description = "Select a folder";
            folderBrowser.SelectedPath = this.txt_LocalDir.Text;
            if (folderBrowser.ShowDialog() == DialogResult.OK)
            {
                this.localDir = folderBrowser.SelectedPath;
                this.txt_LocalDir.Text = this.localDir;               
            }
        }

        //PlayBack Log加载
        private void btn_LoadData_Click(object sender, EventArgs e)
        {           
            try
            {
                //Log File List清理
                this.m_PlayManager.CloseLogFile();

                string logFilePath = this.txt_LocalDir.Text.Trim();
                
                this.cbx_SelectedHour.Items.Clear();
                this.m_PlayManager.getLocalLogFile("N", this.dtp_LogDate.Value.ToString("yyyyMMdd"), this.cbx_StartTime.Text, this.cbx_EndTime.Text, logFilePath);
                foreach (localLogFileInfo unit in this.m_PlayManager.LogFileList)
                {
                    this.cbx_SelectedHour.Items.Add(unit.m_Hour);
                }
                if (this.cbx_SelectedHour.Items.Count > 0)
                {
                    cbx_SelectedHour.SelectedIndex = 0;

                    this.cbx_SelectedHour.Enabled = true;
                }
                else
                {
                    PopupNotice.DialogPopups("播放日志不存在！！！", " PlayBack Log Is Not Exist.", enumPopupsType.Warning);
                }
            }
            catch (Exception ex)
            {
                //PlayBackControls.m_ErrorLogger.Error(ex.ToString());
                LogHelper.loggerError("在加载PlayBack Log数据时报错",ex);
            }           
        }
    

        /// <summary>
        /// 加载每个选中小时的回放日志
        /// </summary>
        private void LoadLogFileByHour()
        {
            //1.每个小时的Log File数据标签读取           
            this.m_PlayManager.GenerateLogData(Convert.ToInt32(this.cbx_SelectedHour.Text));
            if (this.m_PlayManager.logCount == 0)
            {
                if (this.curHourIndex < this.cbx_SelectedHour.Items.Count -1)
                {
                    PopupNotice.DialogPopups("所选小时播放日志无内容！！！", "Selected Hour PlayBack Log No Content.", enumPopupsType.Warning);
                }
                else
                {
                    PopupNotice.DialogPopups("回放日志不存在，请检查！！！", "PlayBack Log Not Exist", enumPopupsType.Warning);
                }

                if (this.curHourIndex < this.cbx_SelectedHour.Items.Count - 1)
                {
                    this.onReading = true;
                    this.BeginInvoke(new Action(() => { this.cbx_SelectedHour.SelectedIndex = this.curHourIndex + 1; }));
                }
                else
                {
                    this.onPlaying = false;
                    this.OnPlayBackComplete();
                }
            }
            else
            {  
                //2.数据Index变更 + 进度条变更
                this.playEndIndex = this.m_PlayManager.logCount - 1;
                this.curIndex = 0;     
                this.trackBar.Minimum = 1;
                this.trackBar.Maximum = (int)Math.Ceiling((double)this.m_PlayManager.logCount / 20.0);

                //3.按钮使能
                this.cbx_Speed.Enabled = true;
                this.btnPlay.Enabled = true;
                this.btnStop.Enabled = true;
                this.trackBar.Enabled = true;

                //4.文件读取完毕 + 数据加载完毕
                this.onReading = false;
            }
        }

        //当前Hour时间内，对应Page Number的Play Back Data加载和读取 -> 生成DataTable
        private void loadPageData(int page)
        {
            this.m_PlayManager.GetXmlDatatPage(page);          
        }

        private async void LogDataPlayBack()
        {           
            await Task.Factory.StartNew(() =>
            {
                while (this.onPlaying)
                {
                    try
                    {
                        if (!onReading)
                        {
                            //1.播放延迟
                            Thread.Sleep(this.delayTime);

                            //2.已有数据翻页 -> 加载新的Data Table + 修改TrackBar的进度
                            int pagNumber = (int)Math.Ceiling((double)(this.curIndex + 1) / 20.0);          //Page Number -> 对应Track Bar的值
                            if (pagNumber != this.trackBarValue)
                            {
                                OnTrackBarChange(pagNumber);  //Track Bar修改
                                this.loadPageData(pagNumber); //数据源更新
                                trackBarValue = pagNumber;
                            }

                            //3.从DataTable获取行数据 + 修改显示时间
                            int curRow = this.curIndex % 20;
                            string dataString = string.Empty;
                            if (this.m_PlayManager.DataList.Rows[curRow] != null)
                            {
                                dataString = string.Empty + this.m_PlayManager.DataList.Rows[curRow]["data"].ToString();
                                string str = this.m_PlayManager.DataList.Rows[curRow]["datetime"].ToString();
                                OnTimeChange(str);  //Time变更
                            }

                            //4.string还原成对象并发布Event
                            if (!string.IsNullOrEmpty(dataString))
                            {
                                string[] ObjectList = dataString.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                                for (int i = 1; i < ObjectList.Length; i++)
                                {
                                    int index = ObjectList[i].IndexOf('@');
                                    if (index == -1) continue;

                                    string reportName = ObjectList[i].Substring(0, index);                                  //获取每种类型对象名字
                                    string allData = ObjectList[i].Substring(index + 1, ObjectList[i].Length - index - 1);  //获取每种类型的所有对象String
                                    if (!m_OldStringDic.ContainsKey(reportName) || m_OldStringDic[reportName] != allData)
                                    {
                                        PlaybackEventHandler?.Invoke(reportName, allData);
                                        m_OldStringDic[reportName] = allData;
                                    }
                                }
                            }

                            //5.当前播放进度自增 + 播放的Hour自增 + PlayBack播放结束暂停
                            if (this.curIndex < this.playEndIndex)
                            {
                                this.curIndex++;
                            }
                            else if (this.curHourIndex < this.cbx_SelectedHour.Items.Count - 1)
                            {
                                this.onReading = true;
                                this.BeginInvoke(new Action(() => { this.cbx_SelectedHour.SelectedIndex = this.curHourIndex + 1; }));
                            }
                            else
                            {
                                this.onPlaying = false;
                                this.OnPlayBackComplete();
                            }
                        }
                    }
                    catch(Exception ex)
                    {
                        LogHelper.loggerError("在LogDataPlayBack方法中报错",ex);
                    }
                    
                }
            });
        }
        private void OnTrackBarChange(int num)
        {
            if (this.InvokeRequired) 
                this.BeginInvoke(new Action<int>(OnTrackBarChange), new object[] { num });
            else 
                this.trackBar.Value = num;
        }

        private void OnTimeChange(string str)
        {
            if (this.InvokeRequired)
                this.BeginInvoke(new Action<string>(OnTimeChange), new object[] { str });
            else
                this.lbl_CurTime.Text = str;
        }
        private void OnPlayBackComplete()
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new System.Action(OnPlayBackComplete));
            }
            else
            {
                this.ButtonInitial();
            }
        }
        private void cbx_SelectedHour_SelectedValueChanged(object sender, EventArgs e)
        {
            if (this.curHourIndex != this.cbx_SelectedHour.SelectedIndex)
            {
                this.onReading = true;
                this.curHourIndex = this.cbx_SelectedHour.SelectedIndex;
                this.LoadLogFileByHour();
            }
        }
        private void trackBar_Scroll(object sender, EventArgs e)
        {
            if (this.m_PlayManager.logCount > 0)
            {
                this.LayoutInitial();
                this.loadPageData(this.trackBar.Value);
                this.setIndexFromGrid();
            }
        }


        private void setIndexFromGrid()
        {           
            if (int.TryParse(string.Empty + this.m_PlayManager.DataList.Rows[0]["index"].ToString(), out int num))
            {
                this.curIndex = num;
            }
        }
       
        private void LogReplay()
        {
            if (this.onPlaying)
            {
                this.LogDataPlayBack();
            }                    
        }
        private void cmbSTime_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (Convert.ToInt32(this.cbx_EndTime.Text) < Convert.ToInt32(this.cbx_StartTime.Text))
            {
                this.cbx_EndTime.Text = Convert.ToInt32(this.cbx_StartTime.Text).ToString("00");
            }
        }

        private void LayoutInitial()
        {
            ////1.页面加载成原始状态
            //this.m_frmMain.ClearCommandAlarmList();
            //this.m_IOManager.ClearAllEventIO();
            //this.m_LayoutManager.BeginUpdate();
            //this.m_LayoutManager.apiClearMap();
            //this.m_LayoutManager.EndUpdate();

            //2.保存的Old String对象清零
            this.m_PlayManager.ClearOldObjectList();
        }

        private void ButtonInitial()
        {
            //1.按钮变更
            this.btnPlay.ImageIndex = 0;
            this.btnStop.Enabled = false;

            //2.停止PlayBack
            this.onPlaying = false;
            this.bPaused = false;

            //3.数据索引还原
            this.curIndex = 0;
            this.cbx_Speed.SelectedIndex = 2;
        }
        private void cmbSpeed_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (this.cbx_Speed.SelectedIndex)
            {
                case 0:
                    this.delayTime = 4000;
                    break;
                case 1:
                    this.delayTime = 2000;
                    break;
                case 2:
                    this.delayTime = 1000;
                    break;
                case 3:
                    this.delayTime = 500;
                    break;
                case 4:
                    this.delayTime = 100;
                    break;
            }
        }

        //PlayBack播放和暂停按钮
        private void btnPlay_Click(object sender, EventArgs e)
        {

            //1.Play Back播放
            if (this.btnPlay.ImageIndex == 0)
            {
                if (this.m_PlayManager.DataList.Rows.Count > 0 )
                {
                    //非暂停的情况下点击播放按钮
                    if (!this.bPaused)
                    {
                        this.LayoutInitial();  //重绘Layout
                    }

                    this.onPlaying = true;
                    this.btnPlay.ImageIndex = 1;
                    this.btnStop.Enabled = true;

                    this.LogReplay();
                }
            }
            //2.Play Back暂停
            else
            {
                this.onPlaying = false;
                this.bPaused = true;
                this.btnPlay.ImageIndex = 0;
            }
        }
        private void btnStop_Click(object sender, EventArgs e)
        {
            //PlayBackControls.m_UILogger.Info("UI : Play Back - Stop Replay");
          
            this.ButtonInitial();
            this.trackBar.Value = 1;
        }

        private void lbdir_Click(object sender, EventArgs e)
        {

        }

        private void txt_LocalDir_TextChanged(object sender, EventArgs e)
        {

        }

        private void pnlControl_Paint(object sender, PaintEventArgs e)
        {

        }

        private void PLPlaybackInfo_Enter(object sender, EventArgs e)
        {

        }

        private void PLPlaybackInfo_Enter_1(object sender, EventArgs e)
        {

        }

        private void cbx_SelectedHour_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}
